package org.example.Thread.Config;

import javassist.bytecode.analysis.Executor;

import java.util.concurrent.*;

/**
 * @Author : zhangbo
 * @data : 2024/6/19
 * @description :
 */
public class ThreadPoolService {
    private static final int CORE_SIZE=Runtime.getRuntime().availableProcessors();
    public ThreadPoolExecutor ExecutorsThreadPool(){
        ThreadPoolExecutor  threadPoolExecutor = new ThreadPoolExecutor(CORE_SIZE*2, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
        threadPoolExecutor.setCorePoolSize(CORE_SIZE*2);
        threadPoolExecutor.setMaximumPoolSize(10);
        threadPoolExecutor.setKeepAliveTime(100,TimeUnit.SECONDS);
        threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
        return threadPoolExecutor;

    }
    public static void main(String[] args) {
        // 设置线程池参数
        int corePoolSize = 7; // 核心线程数
        int maximumPoolSize = Integer.MAX_VALUE; // 最大线程数
        long keepAliveTime = 1; // 非核心线程空闲存活时间
        TimeUnit unit = TimeUnit.MINUTES; // 时间单位
        /**
         * ArrayBlockingQueue——基于数组的阻塞队列，按FIFO，新任务放队尾
         * 有界的数组可以防止资源耗尽问题。
         * 当线程池中线程数量达到corePoolSize后，再有新任务进来，则会将任务放入该队列的队尾，等待被调度。
         * 如果队列已经是满的，则创建一个新线程，
         * 如果线程数量已经达到maxPoolSize，则会执行拒绝策略。
         * LinkedBlockingQuene——基于链表的无界阻塞队列，按照FIFO排序
         * 其实最大容量为Interger.MAX
         * 由于该队列的近似无界性，当线程池中线程数量达到corePoolSize后，再有新任务进来，会一直存入该队列，而不会去创建新线程直到maxPoolSize，
         * 因此使用该工作队列时，参数maxPoolSize其实是不起作用的
         * SynchronousQuene——不缓存任务的阻塞队列
         * 生产者放入一个任务必须等到消费者取出这个任务。
         * 也就是说新任务进来时，不会缓存，而是直接被调度执行该任务，
         * 如果没有可用线程，则创建新线程，如果线程数量达到maxPoolSize，则执行拒绝策略
         * PriorityBlockingQueue——具有优先级的无界阻塞队列
         * 优先级通过参数Comparator实现。
         */
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(); // 工作队列
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 线程工厂
        /**
         * CallerRunsPolicy——主线程自己执行该任务
         * 该策略下，在调用者线程中直接执行被拒绝任务的run方法，除非线程池已经shutdown，否则直接抛弃任务。
         * AbortPolicy——抛出异常
         * 该策略下，直接丢弃任务，并抛出RejectedExecutionException异常
         * DiscardPolicy——直接丢弃
         * 该策略下，直接丢弃任务，什么都不做
         * DiscardOldestPolicy——早删晚进
         * 该策略下，抛弃进入队列最早的那个任务，然后尝试把这次拒绝的任务放入队列
         */
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); // 饱和策略抛出异常
        new ThreadPoolExecutor.DiscardOldestPolicy();//丢弃比较久的任务策略,该策略下，抛弃进入队列最早的那个任务，然后尝试把这次拒绝的任务放入队列
        new ThreadPoolExecutor.CallerRunsPolicy();//主线程自己执行该任务,该策略下，在调用者线程中直接执行被拒绝任务的run方法，除非线程池已经shutdown，否则直接抛弃任务
        new ThreadPoolExecutor.DiscardPolicy();//直接丢弃 该策略下，直接丢弃任务，什么都不做

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );


        // 使用线程池执行任务
        for (int i = 0; i < 10; i++) {
            executor.execute(new Task("Task " + i));
        }

        // 关闭线程池，不再接受新任务，已提交的任务将完成后关闭
        executor.shutdown();
    }

    // 一个简单的任务实现
    static class Task implements Runnable {
        private String taskName;

        public Task(String taskName) {
            this.taskName = taskName;
        }

        @Override
        public void run() {
            System.out.println(taskName + " is running by " + Thread.currentThread().getName());
        }
    }

}
